home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / GX Libraries / TransferModeLibrary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-02  |  9.8 KB  |  345 lines  |  [TEXT/MPS ]

  1.  
  2. /*
  3.     File:        TransferModeLibrary.c
  4.  
  5.     Contains:    graphics libraries - transfer mode library
  6.     
  7.     Written by:    Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  8.     
  9.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <2>      5/1/95    jtd        bringing in final 1.1 source changes
  14.          <1>      1/9/95    JD        First checked in.
  15. */
  16.  
  17. #include <Memory.h>
  18. #include "GraphicsLibraries.h"
  19.  
  20. static void InitColorMatrix(Fixed m[5][4])
  21. {
  22.     register Fixed *x;
  23.     register short i;
  24.  
  25.     x = &m[0][0];
  26.     for(i = 19; i>=0; i--)
  27.         *x++ = 0;
  28.     m[0][0] = m[1][1] = m[2][2] = m[3][3] = fixed1;           /* Identity matrix, for cleanliness */
  29. }
  30.  
  31. /*
  32.   * Initialize all fields of a transfermode record
  33.   * to a very reasonable rgb copy mode.
  34.   */
  35. void InitTransferMode(gxTransferMode *mode)
  36. {
  37.     NilParamReturn(mode);
  38.     SetCommonTransfer(mode,gxCopyMode,0,nil);
  39. }   
  40.  
  41. gxTransferMode *SetCommonTransfer(register gxTransferMode *mode,  commonTransferMode type, unsigned short opValue, const gxColor *opColor)
  42. {
  43.     register gxTransferComponent *component;
  44.     register short i;
  45.     gxColor oColor;
  46.  
  47.     NilParamReturnNil(mode);
  48.  
  49.     if(opColor)
  50.         {
  51.         oColor = *opColor;
  52.         GXConvertColor(&oColor,gxRGBASpace, nil, nil);
  53.         }
  54.     else
  55.         {
  56.         oColor.space = gxRGBASpace;
  57.         oColor.element.rgba.red =
  58.         oColor.element.rgba.green =
  59.         oColor.element.rgba.blue = opValue;
  60.         oColor.element.rgba.alpha = 65535;
  61.         }
  62.  
  63.     if(type >= gxOverMode && type <= gxFadeMode)
  64.         mode->space = gxRGBASpace;
  65.     else
  66.         mode->space = gxRGBSpace;
  67.  
  68.     mode->flags = 0;
  69.     mode->set = nil;
  70.     mode->profile = nil;
  71.  
  72.     component = &mode->component[0];
  73.     InitColorMatrix(mode->sourceMatrix);
  74.     InitColorMatrix(mode->deviceMatrix);
  75.     InitColorMatrix(mode->resultMatrix);
  76.  
  77.     component->mode = type;
  78.     component->flags = 0;
  79.  
  80.     component->sourceMinimum = component->deviceMinimum = component->clampMinimum = 0;
  81.     component->sourceMaximum = component->deviceMaximum = component->clampMaximum = 65535;
  82.  
  83.     for(i = 3; i>=0; i--)
  84.         {
  85.         component = &mode->component[i];
  86.  
  87.         *component = mode->component[0];
  88.         component->operand = (&oColor.element.rgb.red)[i];
  89.  
  90.         switch(type)
  91.             {
  92.             case gxHighlightMode:
  93.                 if(!opColor)                    /* if no opColor passed, use lomem RGBHilite    */
  94.                     component->operand = ((short *)0xDA0)[i];
  95.                 break;
  96.             case gxOverMode:                      /* use it like a real alpha mode                */
  97.                 if(i==3)
  98.                     component->mode = gxRampOrMode;
  99.                 break;
  100.             case gxAtopMode:                      /* use it like a real alpha mode                */
  101.                 if(i==3)
  102.                     {
  103.                     component->flags |= gxReverseComponent;
  104.                     component->mode = gxCopyMode; /* result alpha = device alpha      */
  105.                     }
  106.                 break;
  107.             case gxExcludeMode:                   /* use it like a real alpha mode                */
  108.                 if(i==3)
  109.                     component->mode = gxRampXorMode;
  110.                 break;
  111.             case gxFadeMode:
  112.                 if(i==3)
  113.                     component->mode = gxAddMode;
  114.                 break;
  115.             case commonAddOverMode:
  116.                 component->mode = gxAddMode;
  117.                 component->flags |= gxOverResultComponent;
  118.                 break;
  119.             case commonSubtractOverMode:
  120.                 component->mode = gxAddMode;
  121.                 component->flags |= gxOverResultComponent;
  122.                 mode->sourceMatrix[i][i] = -fixed1;
  123.                 break;
  124.             case commonSubtractPinMode:
  125.                 component->mode = gxAddMode;
  126.                 mode->sourceMatrix[i][i] = -fixed1;
  127.                 break;
  128.             case commonTransparentMode:         /* the opColor specifies which gxColor to avoid from source   */
  129.                 component->mode = gxCopyMode;
  130.                 mode->flags |= gxRejectSourceTransfer;
  131.                 if(opColor)
  132.                     {
  133.                     component->sourceMinimum =
  134.                     component->sourceMaximum = (&oColor.element.rgb.red)[i];
  135.                     }
  136.                 else                            /* default is avoid drawing white */
  137.                     {
  138.                     component->sourceMinimum =
  139.                     component->sourceMaximum = 65535;
  140.                     }
  141.                 break;
  142.             case commonInMode:
  143.                 if(i==3)
  144.                     component->mode = gxRampAndMode;
  145.                 else
  146.                     component->mode = gxCopyMode;
  147.                 break;
  148.             case commonOutMode:
  149.                 if(i==3)
  150.                     {
  151.                     component->mode = gxRampAndMode;
  152.                     mode->deviceMatrix[3][3] = -fixed1;
  153.                     mode->deviceMatrix[4][3] = 65535;
  154.                     }
  155.                 else
  156.                     component->mode = gxCopyMode;
  157.                 break;
  158.  
  159.  
  160.             }
  161.  
  162.         }
  163.  
  164.     return mode;
  165. }
  166.  
  167. void SetInkCommonTransfer(gxInk source, commonTransferMode type)
  168. {
  169.     gxTransferMode mode;
  170.     
  171.     NilInkReturn(source);
  172.     SetCommonTransfer(&mode, type,32768,nil);
  173.     GXSetInkTransfer(source, &mode);
  174. }
  175.  
  176. void SetShapeCommonTransfer(gxShape source, commonTransferMode type)
  177. {
  178.     gxTransferMode mode;
  179.     
  180.     NilShapeReturn(source);
  181.     SetCommonTransfer(&mode, type,32768,nil);
  182.     GXSetShapeTransfer(source, &mode);
  183. }
  184.  
  185. commonTransferMode GetShapeCommonTransfer(gxShape source)
  186. {
  187.     gxTransferMode mode;
  188.     
  189.     NilShapeReturnNil(source);
  190.     GXGetShapeTransfer(source, &mode);
  191.     return mode.component[0].mode;
  192. }
  193.  
  194. commonTransferMode GetInkCommonTransfer(gxInk source)
  195. {
  196.     gxTransferMode mode;
  197.     
  198.     NilInkReturnNil(source);
  199.     GXGetInkTransfer(source, &mode);
  200.     return mode.component[0].mode;
  201. }
  202.  
  203. gxColor *TransmogrifyColor(gxColor *dstColor, const gxColor *srcColor, const gxTransferMode *mode)
  204. {
  205.     gxInk tempInk = GXNewInk();
  206.     
  207.     GXSetInkColor(tempInk,srcColor);
  208.     GXSetInkTransfer(tempInk,mode);
  209.     GXCombineColor(dstColor, tempInk);
  210.     GXDisposeInk(tempInk);
  211.     return dstColor;
  212. }
  213.  
  214. /* Given an gxInk and a device, set's up the gxInk's mode so that drawing over the background gxColor leaves
  215.   * the result gxColor. Also sets up the gxTransferMode gxColorSpace etc. so that the fast case is taken.
  216.   */
  217. void SetInkFastXorTransfer(gxInk inky, gxViewDevice destDevice, gxViewPort destViewPort, gxColor *background, gxColor *result)
  218. {
  219.     gxShape deviceBitsShape;
  220.     gxBitmap deviceBits;
  221.     gxTransferMode fastMode;
  222.     gxColor inkColor;
  223.  
  224.     gxColor localBackground;
  225.     gxColor localResult;
  226.  
  227.     localBackground.space = gxRGBSpace;
  228.     localBackground.profile = nil;
  229.     localBackground.element.rgb.red = 0xFFFF;
  230.     localBackground.element.rgb.green = 0xFFFF;
  231.     localBackground.element.rgb.blue = 0xFFFF;
  232.     
  233.     localResult.space = gxRGBSpace;
  234.     localResult.profile = nil;
  235.     localResult.element.rgb.red = 0;
  236.     localResult.element.rgb.green = 0;
  237.     localResult.element.rgb.blue = 0;
  238.     
  239.     if (background)
  240.         localBackground = *background;
  241.     if (result)
  242.         localResult = *result;
  243.       
  244.     deviceBitsShape = GXGetViewDeviceBitmap(destDevice);
  245.     GXGetBitmap(deviceBitsShape, &deviceBits, nil);
  246.     
  247.      if (destViewPort && (GXGetViewPortAttributes(destViewPort) & gxEnableMatchPort) == 0) {
  248.          localBackground.profile = deviceBits.profile;    /* if drawing through the viewport will disable color matching, we */
  249.          localResult.profile = deviceBits.profile;        /* want to do the same thing for our GXConvertColor calls. */
  250.      }
  251.         
  252.     InitTransferMode(&fastMode);
  253.     fastMode.flags |= gxSingleComponentTransfer;
  254.     fastMode.component[0].mode = gxXorMode;
  255.     if ((fastMode.space = deviceBits.space) == gxIndexedSpace) {
  256.         fastMode.set = deviceBits.set;
  257.         GXConvertColor(&localBackground, gxIndexedSpace, deviceBits.set, deviceBits.profile);
  258.         GXConvertColor(&localResult, gxIndexedSpace, deviceBits.set, deviceBits.profile);
  259.         if (localBackground.element.indexed.index == localResult.element.indexed.index) {
  260.         
  261.                 /* OK, the two colors map into the same index. We will instead use black and white */
  262.         localBackground.space = gxRGBSpace;
  263.         localBackground.profile = nil;
  264.         localBackground.element.rgb.red = 0xFFFF;
  265.         localBackground.element.rgb.green = 0xFFFF;
  266.         localBackground.element.rgb.blue = 0xFFFF;
  267.             
  268.         localResult.space = gxRGBSpace;
  269.         localResult.profile = nil;
  270.         localResult.element.rgb.red = 0;
  271.         localResult.element.rgb.green = 0;
  272.         localResult.element.rgb.blue = 0;
  273.             
  274.             GXConvertColor(&localBackground, gxIndexedSpace, deviceBits.set, deviceBits.profile);
  275.             GXConvertColor(&localResult, gxIndexedSpace, deviceBits.set, deviceBits.profile);
  276.         
  277.         if (localBackground.element.indexed.index == localResult.element.indexed.index) {
  278.  
  279.                     if (localResult.element.indexed.index > 1)
  280.                         --localResult.element.indexed.index;
  281.                     else
  282.                         ++localResult.element.indexed.index;     /* This assumes that gxColorSet has at least 2 colors */
  283.         }
  284.         }
  285.         inkColor.space = gxIndexedSpace;
  286.         inkColor.profile = deviceBits.profile;
  287.         inkColor.element.indexed.set = deviceBits.set;
  288.         inkColor.element.indexed.index = ((localBackground.element.indexed.index - 1) ^
  289.                                 (localResult.element.indexed.index - 1)) + 1;
  290.     } else {
  291.         fastMode.space = gxRGBSpace;
  292.         GXConvertColor(&localBackground, gxRGBSpace, nil, deviceBits.profile);
  293.         GXConvertColor(&localResult, gxRGBSpace, nil, deviceBits.profile);
  294.         inkColor.space = gxRGBSpace;
  295.         inkColor.profile = deviceBits.profile;
  296.         inkColor.element.rgb.red = localBackground.element.rgb.red ^ localResult.element.rgb.red;
  297.         inkColor.element.rgb.green = localBackground.element.rgb.green ^ localResult.element.rgb.green;
  298.         inkColor.element.rgb.blue = localBackground.element.rgb.blue ^ localResult.element.rgb.blue;
  299.     }
  300.     GXSetInkColor(inky, &inkColor);
  301.     GXSetInkTransfer(inky, &fastMode);
  302.     GXDisposeShape(deviceBitsShape);
  303. }
  304.  
  305. void SetShapeFastXorTransfer(gxShape source, gxColor *background, gxColor *result)
  306. {
  307.     long viewPortCount;
  308.  
  309.     viewPortCount = GXGetTransformViewPorts(GXGetShapeTransform(source), nil);
  310.     if( viewPortCount ) {
  311.         gxViewPort vp;
  312.         gxViewDevice vd;
  313.         gxInk inky;
  314.         long viewDeviceCount;
  315.         void *buffer = NewPtr( sizeof(gxViewPort) * viewPortCount );
  316.  
  317. #ifdef debugging
  318.         if (MemError()) Debugger();
  319. #endif
  320.         GXGetTransformViewPorts(GXGetShapeTransform(source), (gxViewPort *)buffer);
  321.  
  322.         if( viewDeviceCount = GXGetViewPortViewDevices(vp = *(gxViewPort *)buffer, nil) ) {
  323.             SetPtrSize((Ptr) buffer, viewDeviceCount * sizeof(gxViewDevice));
  324.             if (MemError())
  325.             {   DisposePtr((Ptr) buffer);
  326.                 buffer = NewPtr(viewDeviceCount * sizeof(gxViewDevice));
  327. #ifdef debugging
  328.                 if (MemError()) Debugger();
  329. #endif
  330.             }
  331.             GXGetViewPortViewDevices(vp, (gxViewDevice *)buffer);
  332.             vd = *(gxViewDevice *)buffer;
  333.         
  334.             if (GXGetInkOwners(inky = GXGetShapeInk(source)) > 1) {
  335.                 GXSetShapeInk(source, inky = GXNewInk());
  336.                 GXDisposeInk(inky);
  337.             }
  338.             SetInkFastXorTransfer(inky, vd, vp, background, result);
  339.             GXSetShapeInkAttributes(source, GXGetShapeInkAttributes(source) | gxSuppressDitherInk);
  340.         }
  341.  
  342.         DisposePtr((Ptr) buffer);
  343.     }
  344. }
  345.